//! Variable and constant declaration parsing

use super::super::{parse_expression, parse_type, Parser};
use crate::ast::decl::{ConstantDecl, VariableDecl};
use crate::error::{CompilerError, Result};
use crate::lexer::token::Token;

/// Parse variable declaration statement
pub fn parse_variable_declaration(parser: &mut Parser) -> Result<VariableDecl> {
    parser.expect(&Token::Var)?;

    if let Some(Token::Identifier(name)) = parser.peek().map(|t| &t.token) {
        let var_name = name.clone();
        parser.advance()?;

        // Check if there's a type annotation
        // If next token is '=', then no type annotation (type inference)
        // Otherwise, try to parse a type
        let var_type = if parser.check(&Token::Assign) {
            // Type inference: var name = value
            None
        } else {
            // Explicit type: var name type = value
            parse_type(parser)?
        };

        // Initializer is required for type inference, optional with explicit type
        let initializer = if parser.consume(&Token::Assign)? {
            parse_expression(parser)?
        } else {
            None
        };

        // Validate: if no type, must have initializer for type inference
        if var_type.is_none() && initializer.is_none() {
            return Err(CompilerError::syntax(
                parser.current_location().line,
                parser.current_location().column,
                "Variable declaration requires either type annotation or initializer. Use: var name type or var name = value",
            ));
        }

        // 可选的分号，支持无分号语法
        parser.consume(&Token::Semicolon)?;

        Ok(VariableDecl {
            name: var_name,
            var_type,
            initializer,
            mutable: true, // Variables are mutable by default in NRC
            location: parser.current_location(),
        })
    } else {
        Err(CompilerError::syntax(
            parser.current_location().line,
            parser.current_location().column,
            "Expected variable name after 'var'",
        ))
    }
}

/// Parse constant declaration statement
pub fn parse_constant_declaration(parser: &mut Parser) -> Result<ConstantDecl> {
    parser.expect(&Token::Const)?;

    if let Some(Token::Identifier(name)) = parser.peek().map(|t| &t.token) {
        let const_name = name.clone();
        parser.advance()?;

        let const_type = if parser.consume(&Token::Colon)? {
            parse_type(parser)?
        } else {
            None
        };

        parser.expect(&Token::Assign)?;

        let value = parse_expression(parser)?;
        if value.is_none() {
            return Err(CompilerError::syntax(
                parser.current_location().line,
                parser.current_location().column,
                "Expected value after '='",
            ));
        }

        parser.expect(&Token::Semicolon)?;

        Ok(ConstantDecl {
            name: const_name,
            const_type,
            value: value.unwrap(),
            location: parser.current_location(),
        })
    } else {
        Err(CompilerError::syntax(
            parser.current_location().line,
            parser.current_location().column,
            "Expected constant name after 'const'",
        ))
    }
}
